现象
CAN滤波器不正常工作;F4的双路CAN不正常工作。
原因
CAN滤波器设置为32位时,需要向左移动固定位作为滤波,这是STM32底层的规则,HAL库没有屏蔽;
STM32F407的双路CAN,CAN1作为CAN0的从机,需要设置更多的内容,用同一个队列,但是滤波器起始不同。
F1:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
|
CAN_FilterTypeDef sFilterConfig; HAL_StatusTypeDef HAL_Status;
sFilterConfig.FilterBank = 0; sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK; sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;
sFilterConfig.FilterIdHigh = (app->app_io->address + (app->device_type << 8)) << CAN_TI0R_EXID_Pos; sFilterConfig.FilterIdLow = 0;
sFilterConfig.FilterMaskIdHigh = 0x1FFF << CAN_TI0R_EXID_Pos; sFilterConfig.FilterMaskIdLow = 0; sFilterConfig.FilterFIFOAssignment = CAN_FILTER_FIFO0;
sFilterConfig.FilterActivation = ENABLE; sFilterConfig.SlaveStartFilterBank = 0;
if (hcan.State == HAL_CAN_STATE_LISTENING) HAL_Status = HAL_CAN_Stop(&hcan); HAL_Status = HAL_CAN_ConfigFilter(&hcan, &sFilterConfig); HAL_Status = HAL_CAN_Start(&hcan); HAL_Status = HAL_CAN_ActivateNotification(&hcan, CAN_IT_RX_FIFO0_MSG_PENDING);
|
1
| HAL_CAN_AddTxMessage(&hcan, &TxMessage, data, (uint32_t*)&mailbox);
|
F4:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| CAN_FilterTypeDef sFilterConfig; HAL_StatusTypeDef HAL_Status;
sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK; sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;
sFilterConfig.FilterIdHigh = 0; sFilterConfig.FilterIdLow = 0;
sFilterConfig.FilterMaskIdHigh = 0; sFilterConfig.FilterMaskIdLow = 0; if (hcan == &hcan1) { sFilterConfig.FilterBank = 0; } else { sFilterConfig.FilterBank = 14; } sFilterConfig.FilterFIFOAssignment = CAN_FILTER_FIFO0; sFilterConfig.SlaveStartFilterBank = 14; sFilterConfig.FilterActivation = ENABLE;
if (hcan->State == HAL_CAN_STATE_LISTENING) HAL_Status = HAL_CAN_Stop(hcan); HAL_Status = HAL_CAN_ConfigFilter(hcan, &sFilterConfig); HAL_Status = HAL_CAN_Start(hcan); HAL_Status = HAL_CAN_ActivateNotification(hcan, CAN_IT_RX_FIFO0_MSG_PENDING);
|
1
| HAL_CAN_AddTxMessage(&hcan, &TxMessage, data, (uint32_t*)&mailbox);
|
其它注意点
需要在STM32CUBEMX中打开的中断只有:
1 2 3 4
| F1: CAN RX1 interrupts F4: CAN RX0 interrupts
|
需要打开:
1 2
| Automatic Bus-off Management Automatic Wake-Up mode
|
以防止CAN死掉;
波特率计算方法是:
1 2 3
| (Time Quanta in Bit Segment 1) + (Time Quanta in Bit Segment 2) + 1 = 9 bit 9Bit * Time Quantum = 9 * 444.444ns = 4000ns 1/4000ns = 250kHz
|
CAN通信的波特率必须完全匹配,硬线上可能会出现负电压。
2019.9.23:
STM32CubeMX中有一项配置,自动重传:配置的期望和代码生成的结果正好是相反的,一定要注意。